/*
* $Id: NavigationWin.cpp 46 2010-02-28 22:01:59Z volok-aleksej@yandex.ru $
*
* Copyright 2008-2009 by Volokitin Alexey
* All rights reserved
*
*/
#include "Common/include.h"
#include "Database/Tables/PointsTable.h"
#include "Database/Tables/FamiliesTable.h"
#include "NavigationWin.h"
#include "Event/EventId.h"

#define MENU_ADD_POINT_ID       0x1
#define MENU_DELETE_POINT_ID    0x2
#define MENU_CHANGE_POINT_ID    0x3
#define MENU_ADD_FAMILY_ID      0x4
#define MENU_CHANGE_FAMILY_ID   0x5
#define MENU_DELETE_FAMILY_ID   0x6
#define MENU_ADD_INSPECT_ID     0x7

CNavigationWin::CNavigationWin(){
	IApplication::GetApp()->GetEventManager()->SubscribeEvent(this, POINTS_DB_CHANGE_EVENT);
	IApplication::GetApp()->GetEventManager()->SubscribeEvent(this, FAMILIES_DB_CHANGE_EVENT);
}
CNavigationWin::~CNavigationWin(){
	IApplication::GetApp()->GetEventManager()->UnSubscribeEvent(this, POINTS_DB_CHANGE_EVENT);
	IApplication::GetApp()->GetEventManager()->UnSubscribeEvent(this, FAMILIES_DB_CHANGE_EVENT);
}

void CNavigationWin::WindowCreate(CWnd* pParentWin){
	Create(WS_CHILD | WS_VISIBLE | WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT |
			TVS_EDITLABELS | TVS_FULLROWSELECT | TVS_SHOWSELALWAYS,
			CRect(0,0,0,0), pParentWin, TREE_NAVIGATION_WND_ID);
	Reload();
}

void CNavigationWin::EventHandler(){
	Reload();
}
/************************************************************************/
/*                        Message Function                              */
/************************************************************************/
BEGIN_MESSAGE_MAP(CNavigationWin, CTreeCtrl)
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(MENU_ADD_POINT_ID, OnAddPoint)
	ON_COMMAND(MENU_ADD_FAMILY_ID, OnAddFamily)
	ON_COMMAND(MENU_ADD_INSPECT_ID, OnAddInspect)
	ON_COMMAND(MENU_CHANGE_POINT_ID, OnChangePoint)
	ON_COMMAND(MENU_CHANGE_FAMILY_ID, OnChangeFamily)
	ON_COMMAND(MENU_DELETE_FAMILY_ID, OnDeleteFamily)
	ON_COMMAND(MENU_DELETE_POINT_ID, OnDeletePoint)
END_MESSAGE_MAP()

void CNavigationWin::OnRButtonDown(UINT nFlags, CPoint point){
	HTREEITEM htreeItem = HitTest(point);
	SelectItem(htreeItem);
	CreateMenu(point);
//	__super::OnRButtonDown(nFlags, point);
}
void CNavigationWin::OnLButtonDown(UINT nFlags, CPoint point){
	__super::OnLButtonDown(nFlags, point);
	HTREEITEM htreeItem = HitTest(point);
	SelectItem(htreeItem);
}
void CNavigationWin::OnContextMenu(CWnd* pWnd, CPoint pos){
	HTREEITEM item = GetSelectedItem();
	CRect rect;
	if(item){
		GetItemRect(item, rect, false);
		CreateMenu(CPoint(rect.Width()/2, rect.top + rect.Height()/2));
	}else{
		GetClientRect(rect);
		CreateMenu(CPoint(rect.Width()/2, 0));
	}
}

void CNavigationWin::OnAddPoint(){
	ItemManipulation(JournalEnum::ADD_POINT);
}
void CNavigationWin::OnAddFamily(){
	ItemManipulation(JournalEnum::ADD_FAMILY);
}
void CNavigationWin::OnAddInspect(){
	ItemManipulation(JournalEnum::ADD_INSPECT);
}
void CNavigationWin::OnChangePoint(){
	ItemManipulation(JournalEnum::CHANGE_POINT);
}
void CNavigationWin::OnChangeFamily(){
	ItemManipulation(JournalEnum::CHANGE_FAMILY);
}
void CNavigationWin::OnDeletePoint(){
	ItemManipulation(JournalEnum::DELETE_POINT);
}
void CNavigationWin::OnDeleteFamily(){
	ItemManipulation(JournalEnum::DELETE_FAMILY);
}

/************************************************************************/
/*                          User Function                               */
/************************************************************************/
void CNavigationWin::Reload(){
	DeleteAllItems();
	IDatabase* pDb = IApplication::GetApp()->GetDatabaseManager()->OpenDatabase(JOURNAL_DATABASE_NAME);
	CPointsTable points;
	IResult* result = points.GetValue(pDb);
	for(int i = 0; i < (int)result->GetSizeResult(); i++){
		CPointsTable::content* pContent = (CPointsTable::content*)(*result)[i];
		HTREEITEM item = InsertItem(pContent->s_strName.c_str());
		SetItemData(item, MAKELONG(JournalEnum::POINT, pContent->s_nId));
		CFamiliesTable families;
		families.m_content.s_nIdPoint = pContent->s_nId;
		IResult* result1 = families.GetValue(pDb);
		for(int j = 0; j < (int)result1->GetSizeResult(); j++){
			CFamiliesTable::content* pContent1 = (CFamiliesTable::content*)(*result1)[j];
			HTREEITEM item1 = InsertItem(pContent1->s_strName.c_str(), item);
			SetItemData(item1, MAKELONG(JournalEnum::FAMILY, pContent1->s_nId));
		}
		result1->Free();
	}
	result->Free();
	IApplication::GetApp()->GetDatabaseManager()->CloseDatabase(pDb);
}
void CNavigationWin::SetMenuItem(CMenu* menu, int nNum, int nId, const std::tstring& strText, BOOL bSep)
{
	MENUITEMINFO mii;
	mii.cbSize = sizeof(MENUITEMINFO);
	mii.fMask = MIIM_DATA | MIIM_STATE | MIIM_TYPE | MIIM_ID;
	mii.fState = MFS_ENABLED;
	if(!bSep)
	{
		mii.fType = MFT_STRING;
		mii.wID = nId;
		mii.dwTypeData = (TCHAR*)strText.c_str();
	}
	else
		mii.fType = MFT_SEPARATOR;
	menu->InsertMenuItem(nNum, &mii);
}
void CNavigationWin::CreateMenu(CPoint pos)
{
	CMenu menu;
	HTREEITEM item = GetSelectedItem();
	if(menu.CreatePopupMenu())
	{
		long p = 0;
		if(item)
			p = (long)GetItemData(item);
		if(!item || !GetItemData(item))
			SetMenuItem(&menu, 0, MENU_ADD_POINT_ID, IApplication::GetApp()->GetLanguageManager()->GetString(ADD_POINT_ID), FALSE);
		else if(LOWORD(p) == JournalEnum::POINT)
		{
			SetMenuItem(&menu, 0, MENU_ADD_FAMILY_ID, IApplication::GetApp()->GetLanguageManager()->GetString(ADD_FAMILY_ID), FALSE);
			SetMenuItem(&menu, 1, MENU_CHANGE_POINT_ID, IApplication::GetApp()->GetLanguageManager()->GetString(CHANGE_POINT_ID), FALSE);
			SetMenuItem(&menu, 2, MENU_DELETE_POINT_ID, IApplication::GetApp()->GetLanguageManager()->GetString(DELETE_POINT_ID), FALSE);
		}
		else if(LOWORD(p) == JournalEnum::FAMILY)
		{
			SetMenuItem(&menu, 0, MENU_ADD_INSPECT_ID, IApplication::GetApp()->GetLanguageManager()->GetString(ADD_INSPECT_ID), FALSE);
			SetMenuItem(&menu, 1, MENU_CHANGE_FAMILY_ID, IApplication::GetApp()->GetLanguageManager()->GetString(CHANGE_FAMILY_ID), FALSE);
			SetMenuItem(&menu, 2, MENU_DELETE_FAMILY_ID, IApplication::GetApp()->GetLanguageManager()->GetString(DELETE_FAMILY_ID), FALSE);
		}
		CRect rect;
		GetWindowRect(rect);
		menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, rect.left + pos.x, rect.top + pos.y, this);
	}
}

void CNavigationWin::ItemManipulation(JournalEnum::typeItemMnpl item){
	IWnd* pWnd = IApplication::GetApp()->GetVisualManager()->GetVisualComponent(
		IApplication::GetApp()->GetLanguageManager()->GetString(JOURNAL_CAPTION_ID))->GetComponentFrame();
	HTREEITEM nSelItem = GetSelectedItem();
	std::tstring strTitle, 
	strText = IApplication::GetApp()->GetLanguageManager()->GetString(QUESTION_DELETE_ID) + _T(" '") + GetItemText(nSelItem).GetString() + _T("'?");
	if(item == JournalEnum::DELETE_POINT)
		strTitle = IApplication::GetApp()->GetLanguageManager()->GetString(DELETE_POINT_ID);
	else if(item == JournalEnum::DELETE_FAMILY)
		strTitle = IApplication::GetApp()->GetLanguageManager()->GetString(DELETE_FAMILY_ID);
	if((item == JournalEnum::DELETE_POINT || item == JournalEnum::DELETE_FAMILY) &&
	dynamic_cast<CWnd*>(pWnd)->MessageBox(strText.c_str(),strTitle.c_str(), MB_YESNO) == IDNO)
		return;
	long p = 0;
	if(nSelItem)
		p = (long)GetItemData(nSelItem);
	pWnd->Send(UM_ITEM_MANIPULATION, item, HIWORD(p));
	if(item == JournalEnum::DELETE_POINT || item == JournalEnum::DELETE_FAMILY)
		DeleteItem(nSelItem);
}
